#pragma once

/*
 * raft 节点与其他节点的 rpc 通讯
 * 相当于 rpc 的客户端
 */

#include <memory>

#include "bq_log/bq_log.h"
#include "raft_core/rpc_proto/raft_rpc.grpc.pb.h"
#include "raft_core/rpc_proto/raft_rpc.pb.h"

namespace raft::core {
    class RaftSender {
    public:
        RaftSender(const std::string& ip, short port);

        ~RaftSender() = default;

        // 对应 leader 向 follower 复制日志或者发送心跳的 RPC 调用
        bool append_entries(const raft_rpc_protoc::AppendEntries& request,
                            raft_rpc_protoc::AppendEntriesReply* reply);

        // 在 leader 选举阶段候选人发起请求投票的 rpc 调用
        bool request_election(const raft_rpc_protoc::RequestElection& request,
                              raft_rpc_protoc::RequestElectionReply* reply);

        // leader 向 follewer 发送安装快照的 rpc 调用
        bool install_snapshot(const raft_rpc_protoc::InstallSnapshot& request,
                              raft_rpc_protoc::InstallSnapshotReply* reply);

        [[nodiscard]] std::string get_me() const;

    private:
        std::unique_ptr<raft_rpc_protoc::RaftRPC::Stub> stub_;

        // 节点标识
        std::string me_;

        bq::log log;
    };
}// namespace raft::core